package com.swak.frame.http;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.google.common.collect.Maps;
import okhttp3.OkHttpClient;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.Charset;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class RestTemplateBuilder {

    private int readTimeout = 5000;

    private int writeTimeout = 5000;

    private int connectTimeout = 5000;

    public static SwakRestTemplate restTemplate() {
        return RestTemplateBuilder.newBuilder().setConnectTimeout(1200).setReadTimeout(1200)
            .setWriteTimeout(1200).build();
    }

    public static SwakRestTemplate restTemplate(int readTimeout, int writeTimeout) {
        return RestTemplateBuilder.newBuilder().setConnectTimeout(1200).setReadTimeout(readTimeout)
            .setWriteTimeout(writeTimeout).build();
    }

    public static RestTemplateBuilder newBuilder() {
        return new RestTemplateBuilder();
    }

    /**
     * Sets the underlying read timeout in milliseconds.
     * A value of 0 specifies an infinite timeout.
     * 
     * @see OkHttpClient.Builder#readTimeout(long, TimeUnit)
     */
    public RestTemplateBuilder setReadTimeout(int readTimeout) {
        this.readTimeout = readTimeout;
        return this;
    }

    /**
     * Sets the underlying write timeout in milliseconds.
     * A value of 0 specifies an infinite timeout.
     * 
     * @see OkHttpClient.Builder#writeTimeout(long, TimeUnit)
     */
    public RestTemplateBuilder setWriteTimeout(int writeTimeout) {
        this.writeTimeout = writeTimeout;
        return this;
    }

    /**
     * Sets the underlying connect timeout in milliseconds.
     * A value of 0 specifies an infinite timeout.
     * 
     * @see OkHttpClient.Builder#connectTimeout(long, TimeUnit)
     */
    public RestTemplateBuilder setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
        return this;
    }

    public SwakRestTemplate build() {
        OkHttp3ClientHttpRequestFactory requestFactory = new OkHttp3ClientHttpRequestFactory();
        requestFactory.setConnectTimeout(this.connectTimeout);
        requestFactory.setReadTimeout(readTimeout);
        requestFactory.setWriteTimeout(writeTimeout);
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        // 换上fastjson
        List<HttpMessageConverter<?>> httpMessageConverterList =
            restTemplate.getMessageConverters();
        Iterator<HttpMessageConverter<?>> iterator = httpMessageConverterList.iterator();
        if (iterator.hasNext()) {
            HttpMessageConverter<?> converter = iterator.next();
            // 原有的String是ISO-8859-1编码 去掉
            if (converter instanceof StringHttpMessageConverter) {
                iterator.remove();
            }
        }
        httpMessageConverterList.add(new StringHttpMessageConverter(Charset.forName("utf-8")));
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter =
            new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
        httpMessageConverterList.add(0, fastJsonHttpMessageConverter);

        return new SwakRestTemplate(restTemplate);
    }


    public static void main(String[] args) {
        SwakRestTemplate restTemplate = RestTemplateBuilder.newBuilder().setConnectTimeout(1000)
            .setReadTimeout(1000).setWriteTimeout(2000).build();
        Map<String, Object> uriVariables = Maps.newHashMap();
        uriVariables.put("token", "jdcb46ab3c2be5a829");
        uriVariables.put("pin", 11111);
        uriVariables.put("dd", new Date());
        JSONObject result = restTemplate.postRequest(
            "http://10.172.136.192/api/jwbd/qryTask?pin=colley_ma", uriVariables, JSONObject.class);
        System.out.println(result.toJSONString());

    }
}
